package com.funcourse.demo.api.restful;

import com.funcourse.demo.aliyun.contentsafe.ContentChecker;
import com.funcourse.demo.aliyun.oss.ObjectTagger;
import com.funcourse.demo.aliyun.oss.OssConfig;
import com.funcourse.demo.api.restful.io.response.ApiResponse;
import com.funcourse.demo.api.restful.io.response.busi.MeVO;
import com.funcourse.demo.api.restful.io.response.error.CommonUsedError;
import com.funcourse.demo.api.restful.io.response.error.ComplianceError;
import com.funcourse.demo.api.restful.security.AuthUserHolder;
import com.funcourse.demo.api.restful.upload.QuestionsCoverPathManager;
import com.funcourse.demo.business.RoomCacher;
import com.funcourse.demo.business.RoomServiceError;
import com.funcourse.demo.model.CompeteRoom;
import com.funcourse.demo.model.repo.CompeteRoomRepo;
import com.funcourse.demo.model.repo.room.RoomNumberRepo;
import com.funcourse.demo.model.room.RoomNumber;
import com.funcourse.demo.sms.SmsSender;
import com.funcourse.demo.sms.vcode.VerifyCodeFunction;
import com.funcourse.demo.sms.vcode.VerifyCodeGenerator;
import com.funcourse.demo.sms.vcode.VerifyCodeManager;
import com.funcourse.demo.sms.vcode.VerifyCodeMongoBean;
import com.funcourse.demo.util.PicVerifyCodeUtil;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
import javax.imageio.ImageIO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

@CrossOrigin(origins = "*")
@Slf4j
@RestController
@RequestMapping("#{'/api/'+'${service.version}'+'/common'}")
public class CommonController {

  @Autowired
  SmsSender smsSender;

  @Autowired
  AuthUserHolder authUserHolder;

  @Autowired
  VerifyCodeGenerator verifyCodeGenerator;

  @Autowired
  VerifyCodeManager verifyCodeManager;
  @Autowired
  QuestionsCoverPathManager questionsCoverPathManager;
  @Autowired
  OssConfig ossConfig;
  @Autowired
  CompeteRoomRepo competeRoomRepo;
  @Autowired
  RoomCacher roomCacher;
  @Autowired
  RoomNumberRepo roomNumberRepo;
  @Autowired
  ContentChecker contentChecker;

  @Autowired
  ObjectTagger objectTagger;

  @ApiOperation(value = "获取图形验证码")
  @GetMapping(value = "/getPicVerifyCode",produces = "image/jpeg")
  public ResponseEntity<Resource> getPicVerifyCode(String mobile) throws IOException {
    VerifyCodeMongoBean picVerifyCodeMongoBean = verifyCodeManager
        .allocateVerifyCode(mobile, VerifyCodeFunction.PIC_VERIFY);
    BufferedImage authImg = PicVerifyCodeUtil.getAuthImg(picVerifyCodeMongoBean.getVerifyCode());
    ByteArrayOutputStream os = new ByteArrayOutputStream();
    ImageIO.write(authImg, "jpeg", os);
    return ResponseEntity.ok(new InputStreamResource(new ByteArrayInputStream(os.toByteArray())));
  }

  @ApiOperation(value = "获取用户信息")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "Authorization", value = "Authorization", paramType = "header", required = true)
  })
  @GetMapping(value = "/getUserInfo")
  public ApiResponse<MeVO> getUserInfo() {
    return new ApiResponse(CommonUsedError.SUCCESS,new MeVO(authUserHolder.getAuthUser()));
  }

  /**view room compete rank
   * room id
   * room info
   */
  @ApiOperation(value = "查看参加过的房间")
  @PostMapping("/viewRoomInfo")
  public ApiResponse<CompeteRoom> viewRoomInfo(String roomId) {
    CompeteRoom competeRoom = roomCacher.getRoomById(roomId);
    if (null != competeRoom) {
      return new ApiResponse(CommonUsedError.SUCCESS, competeRoom);
    }
    return new ApiResponse(CommonUsedError.BAD_REQUEST.customizedError("no room found"), null);
  }

  /**
   * room number
   * room info
   */
  @ApiOperation(value = "根据房间号查看房间信息")
  @PostMapping("/viewRoomInfoByNumber")
  public ApiResponse<CompeteRoom> viewRoomInfoByNumber(String roomNo) {
    List<RoomNumber> byRoomNo = roomNumberRepo.findByRoomNo(roomNo);
    if(CollectionUtils.isEmpty(byRoomNo)){
      return new ApiResponse(RoomServiceError.ROOM_NOT_FOUND,null);
    }
    return  viewRoomInfo(byRoomNo.get(0).getRoomId());
  }

  @ApiOperation(value = "发送短信")
  @PostMapping("/sendSms")
  public ApiResponse sendSms(String mobile,String picVerifyCodeStr){
    //查询图片验证码是否有效
//    VerifyCodeMongoBean picVerifyCodeMongoBean = verifyCodeManager
//        .doVerifyCode(mobile, VerifyCodeFunction.PIC_VERIFY, picVerifyCodeStr);
//    if(null == picVerifyCodeMongoBean){
//      return new ApiResponse<>(CommonUsedError.BAD_REQUEST,null);
//    }
    //生成短信验证码，并发送
    VerifyCodeMongoBean loginVerifyCode = verifyCodeManager
        .allocateVerifyCode(mobile, VerifyCodeFunction.LOGIN);
    smsSender.sendSms(mobile,loginVerifyCode.getVerifyCode());
    return new ApiResponse<>(CommonUsedError.SUCCESS,null);
  }

  /**
   * upload a picture picbody url
   */
  @ApiOperation(value = "上传图片")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "Authorization", value = "Authorization", paramType = "header", required = true)
  })
  @PostMapping("/uploadImage")
  public ApiResponse<String> uploadImage(@RequestParam("file") MultipartFile file) {
    String pathOfQuestionCover = questionsCoverPathManager.getPathOfQuestionCover();
    try {
      ossConfig.getOssClient()
          .putObject(ossConfig.getBucketName(), pathOfQuestionCover, file.getInputStream());
    } catch (IOException e) {
      log.error("put image failed", e);
      return new ApiResponse(CommonUsedError.SERVER_ERROR, "");
    }
    final String picUrl = ossConfig.getPicDomain() + "/" + pathOfQuestionCover;
    final Boolean imageValid = contentChecker.checkIfImagePass(picUrl);
    if(!imageValid){
      ossConfig.getOssClient().deleteObject(ossConfig.getBucketName(),pathOfQuestionCover);
      return new ApiResponse(ComplianceError.ERROR,
          "pic compliance error");
    }
    objectTagger.increaseOrInitReferenceTag(0,pathOfQuestionCover);
    return new ApiResponse(CommonUsedError.SUCCESS,
        picUrl);
  }

}
